/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package PasswrdChk02.Regras;
import InterfacesPasswordChecker02.DescontosFactory;
import PasswrdChk02.Componentes.Consecutivos;
import PasswrdChk02.Componentes.Sequencias;

/**
 *
 * @author LABCCET
 */
public class Descontos implements DescontosFactory{
    private final int FATOR_DESCONTO_SEQUENCIA = 3; //Sequencias de 3 caracteres sucessivos
    private final int FATOR_DESCONTO_NAO_SIMBOLOS_CONSECUTIVOS = 2; // Para Letras e digitos consecutivos
    String password;
    Consecutivos consecutivos;
    Sequencias sequencias;
    
    public Descontos(String senha) {
        this.password = senha;
        this.consecutivos = new Consecutivos(password);
        this.sequencias = new Sequencias(password);
    }
       
    //-----------------------calcularDescontosCaracteresConsecutivos----------
    @Override
    public int calcularDescontoMaiusculasConsecutivas(){
        
        return consecutivos.SomarMaiusculasConsecutivas()* FATOR_DESCONTO_NAO_SIMBOLOS_CONSECUTIVOS;
    } 
    
    @Override
    public int calcularDescontoMinusculasConsecutivas(){
        return consecutivos.SomarMinusculasConsecutivas()* FATOR_DESCONTO_NAO_SIMBOLOS_CONSECUTIVOS;
    } 
    
    @Override
    public int calcularDescontoDigitosConsecutivos(){
        return consecutivos.SomarDigitosConsecutivos()* FATOR_DESCONTO_NAO_SIMBOLOS_CONSECUTIVOS;
    } 
            //-----------------------calcularDescontosCaracteresConsecutivos----------
    
    
            //-----------------------calcularDescontosGerais------------
    
    @Override
    public int calcularDescontosSequencia(){
        return (this.calcularDescontoSequenciaDeDigitos()+this.calcularDescontoSequenciaDeLiterais()+this.calcularDescontoSequenciaDeSimbolos());
    }
    
    @Override
    public int calcularDescontosTipoUnico(){
        return this.calcularDescontoSomenteDigitos()+this.calcularDescontoSomenteLiterais();
    }
    
    @Override
    public int calcularDescontosCaracteresConsecutivos(){
        return this.calcularDescontoDigitosConsecutivos()+this.calcularDescontoMaiusculasConsecutivas()+this.calcularDescontoMinusculasConsecutivas();
    }
    
            //-----------------------calcularDescontosGerais------------   
     
 //-----------------------calcularDescontosSequencia----------
    @Override
    public int calcularDescontoSequenciaDeLiterais(){
        
        return sequencias.calcularSequenciasDeLiterais()* FATOR_DESCONTO_SEQUENCIA;
    } 
    
    @Override
    public int calcularDescontoSequenciaDeDigitos(){
        return sequencias.calcularSequenciaDeDigitos()* FATOR_DESCONTO_SEQUENCIA;
    }
    
    @Override
    public int calcularDescontoSequenciaDeSimbolos(){
        return sequencias.calcularSequenciaDeSimbolos()* FATOR_DESCONTO_SEQUENCIA;
    }
                //-----------------------calcularDescontosSequencia----------           
    
//-----------------------calcularDescontosCaracteresTipoUnico----------
    @Override
    public int calcularDescontoSomenteLiterais(){
        
       return isAlphasOnly()? password.length():0;
   } 
    
    @Override
    public int calcularDescontoSomenteDigitos(){
       return isDigitsOnly()? password.length():0;
    } 
            //-----------------------calcularDescontosCaracteresTipoUnico------------
    
    
                //-----------------------calcularDescontosCaracteresRepetidos----------
    @Override
    public int calcularDescontoRepetiçãoDeCaracteres(){
        
        char[] senhaSemEspacos = password.replaceAll("\\s+","").toCharArray();
        boolean existeCaractereRepetido;
        int comprimentoSenha = senhaSemEspacos.length;
        double indiceRepeticao = 0.0;
        int caracteresRepetidos = 0;
        int caracteresUnicos =0;
                
                    for (int i=0; i < comprimentoSenha; i++){
                        existeCaractereRepetido = false;
			for (int b=0; b < comprimentoSenha; b++) {
                           if (senhaSemEspacos[i] == senhaSemEspacos[b] && i != b) {
                                existeCaractereRepetido = true;
                               indiceRepeticao += Math.abs((double)comprimentoSenha/(b-i));
                            }
			}
			if (existeCaractereRepetido) {
				caracteresRepetidos++;
				caracteresUnicos = comprimentoSenha-caracteresRepetidos;
				indiceRepeticao = (caracteresUnicos != 0) ? (int)Math.ceil(indiceRepeticao/caracteresUnicos) : (int)Math.ceil(indiceRepeticao);
			}
                   }   
     return (int)indiceRepeticao;
    }

    @Override
    public boolean isAlphasOnly() {
        for (char ch : password.toCharArray()) {
            if (!Character.isLetter(ch)) {
                return false;
            }
        }
        return !password.isEmpty();
    }

    @Override
    public boolean isDigitsOnly() {
        for (char ch : password.toCharArray()) {
            if (!Character.isDigit(ch)) {
                return false;
            }
        }
        return !password.isEmpty();
    }

    @Override
    public int calcularDescontos() {
        return calcularDescontosSequencia() + calcularDescontosTipoUnico() + calcularDescontosCaracteresConsecutivos() + calcularDescontoRepetiçãoDeCaracteres();
    }

}
                    //-----------------------calcularDescontosCaracteresRepetidos----------